/*
 * Copyright (C) 2018 Hisilicon Limited.
 *
 * this program is for pcie ap dma comm
 *
 * This program is free software; you can redistribute it and /or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version
 */

#ifndef _APB_COMM_DRV_H_
#define _APB_COMM_DRV_H_

#include <linux/sched.h>
#include <asm/io.h>
#include "drv_log.h"
#include "devdrv_atu.h"

#define module_devdrv "drv_pcie"
#define devdrv_err(fmt, ...)                                                                                  \
    do {                                                                                                      \
        drv_err(module_devdrv, "<%s:%d:%d> " fmt, current->comm, current->tgid, current->pid, ##__VA_ARGS__); \
    } while (0);
#define devdrv_info(fmt, ...)                                                                                  \
    do {                                                                                                       \
        drv_info(module_devdrv, "<%s:%d:%d> " fmt, current->comm, current->tgid, current->pid, ##__VA_ARGS__); \
    } while (0);

#define RX_ATU_FUNC_MODE_OFFSET 1
#define RX_ATU_FUNC_MODE_MASK (0x1 << RX_ATU_FUNC_MODE_OFFSET)
#define RX_ATU_FUNC_MODE_PF 0
#define RX_ATU_ENABLE_OFFSET 0
#define RX_ATU_ENABLEE_MASK (0x1 << RX_ATU_ENABLE_OFFSET)
#define RX_ATU_PF_NUM_OFFSET 3
#define RX_ATU_PF_NUM_MASK (0x7 << RX_ATU_PF_NUM_OFFSET)
#define RX_ATU_BAR_NUM_OFFSET 0
#define RX_ATU_BAR_NUM_MASK (0x7 << RX_ATU_BAR_NUM_OFFSET)


#define TX_ATU_PF_NUM_OFFSET 5
#define TX_ATU_PF_NUM_MASK (0x7 << TX_ATU_PF_NUM_OFFSET)
#define TX_ATU_EP_NUM_OFFSET 4
#define TX_ATU_EP_NUM_MASK (0x1 << TX_ATU_EP_NUM_OFFSET)
#define TX_ATU_EP_NUM_CORE1_PORT0 0
#define TX_ATU_TYPE_TRANS_MODE_OFFSET 2
#define TX_ATU_TYPE_TRANS_MODE_MASK (0x1 << TX_ATU_TYPE_TRANS_MODE_OFFSET)
#define TX_ATU_TYPE_TRANS_MODE_MEM 0
#define TX_ATU_TYPE_TRANS_MODE_IO 1
#define TX_ATU_WORK_MODE_OFFSET 1
#define TX_ATU_WORK_MODE_MASK (0x1 << TX_ATU_WORK_MODE_OFFSET)
#define TX_ATU_WORK_MODE_EP 1
#define TX_ATU_EN_OFFSET 0
#define TX_ATU_EN_MASK (0x1 << TX_ATU_EN_OFFSET)


#define DEVDRV_DL_DLCMSM_STATE_OFFSET 0
#define DEVDRV_DL_DLCMSM_STATE_BIT (0x7 << DEVDRV_DL_DLCMSM_STATE_OFFSET)
#define DEVDRV_DL_DLCMSM_STATE_OK 0x4
#define DEVDRV_DL_DLCMSM_STATE_TIMEOUT 400000 /* 400ms, given in mini FS */

/* offset in reg H file, move here. Start */

// base addr
#define DEVDRV_DL_REG_BASE_REG_H_FILE 0x106000
#define DEVDRV_AP_IOB_RX_COM_REG_BASE_REG_H_FILE 0x4000

#define DEVDRV_DL_DFX_FSM_STATE (DEVDRV_DL_REG_BASE_REG_H_FILE + 0x58)
#define DEVDRV_RX_ATU_CONTROL0_REG DEVDRV_AP_IOB_RX_COM_REG_BASE_REG_H_FILE
#define DEVDRV_RX_ATU_CONTROL1_REG (DEVDRV_AP_IOB_RX_COM_REG_BASE_REG_H_FILE + 0x4)
#define DEVDRV_RX_ATU_CONTROL2_REG (DEVDRV_AP_IOB_RX_COM_REG_BASE_REG_H_FILE + 0x8)
#define DEVDRV_RX_ATU_REGION_SIZE_REG (DEVDRV_AP_IOB_RX_COM_REG_BASE_REG_H_FILE + 0xC)
#define DEVDRV_RX_ATU_BASE_L_REG (DEVDRV_AP_IOB_RX_COM_REG_BASE_REG_H_FILE + 0x10)
#define DEVDRV_RX_ATU_BASE_H_REG (DEVDRV_AP_IOB_RX_COM_REG_BASE_REG_H_FILE + 0x14)
#define DEVDRV_RX_ATU_TAR_L_REG (DEVDRV_AP_IOB_RX_COM_REG_BASE_REG_H_FILE + 0x18)
#define DEVDRV_RX_ATU_TAR_H_REG (DEVDRV_AP_IOB_RX_COM_REG_BASE_REG_H_FILE + 0x1C)
#define DEVDRV_RX_ATU_REG_SIZE 0x20
#define DEVDRV_RX_ATU_REG_SHOW_OFFSET 16


#define DEVDRV_TX_ATU_CONTROL0_REG 0x0
#define DEVDRV_TX_ATU_CONTROL2_REG 0x8
#define DEVDRV_TX_ATU_REGION_SIZE_REG 0xC
#define DEVDRV_TX_ATU_BASE_L_REG 0x10
#define DEVDRV_TX_ATU_BASE_H_REG 0x14
#define DEVDRV_TX_ATU_TAR_L_REG 0x18
#define DEVDRV_TX_ATU_TAR_H_REG 0x1C
#define DEVDRV_TX_ATU_REG_SIZE 0x20

/* offset in reg H file, move here. End */


int devdrv_check_dlcmsm(const void __iomem *io_base);
int devdrv_get_devid_by_bus(unsigned char bus_number, int *devid);
int agentdrv_get_rc_ep_mode(u32 *mode);

void devdrv_apb_reg_wr(void __iomem *io_base, u32 offset, u32 val);
void devdrv_apb_reg_rd(const void __iomem *io_base, u32 offset, u32 *val);

int devdrv_rx_atu_init(const void __iomem *io_base, u32 pf_num, u32 bar_num, struct devdrv_iob_atu atu[], int num);
void devdrv_add_tx_atu(void __iomem *io_base, u32 atu_id, u32 pf_num, struct devdrv_iob_atu *atu);
void devdrv_del_tx_atu(void __iomem *io_base, u32 atu_id, u32 pf_num, struct devdrv_iob_atu *atu);
int devdrv_get_tx_atu(const void __iomem *io_base, u32 atu_id, u32 pf_num, struct devdrv_iob_atu *atu);

#endif
